﻿/* The entire base for this class resides at
 * http://www.freewebs.com/campelmxna/Articles/MouseCursor.htm
 * I just added tons of comments
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework; // Xna Stuff
using Microsoft.Xna.Framework.Input; // Input Reference we need to include here


/* This is our Mouse Class.
 * It will contain all the functions that our mouse will use
 * It is part of the namespace LandBaron which is the project
 * we are currently working with.
 * And the class name MouseControl can really be any name 
 * we want, I choose MouseControl but it could have been MousePointer or Pointer
 * or any name not in use by this namespace or XNA.
 */
namespace LandBaron
{
    class MouseControl
    {
        /*
         * Setting Up the Variables we are going to be using throughout this class
         * These may change as the game progresses, but its a good start for now
         */
        #region Variables
        // Our Variables
        public MouseState currentmouse; // The state the mouse is currently in

        public MouseState oldmouse; // The last state the mouse was in

        public Vector2 Position; // A 2D position returns and X and a Y

        public Rectangle clickRectangle; //This rectangle will be used to track mouse clicks

        public bool leftIsHeld; // Used to see if we are dragging the mouse with left button held down

        private int screenwidth, screenheight; // The screen size to map out for use with this mouse
        // This is gonna be a pain, because i have to make the screen dynamically resizable, and 
        // Only have a small clue on how to do it lol

        public int scrollWheelValue; // Used for zooming in and out normally, but we can map any funtion to scroll wheel

        private double time; // A way to track Real Time

        private GameTime gametime; // A way to track GameTime

        public bool clickedonce; // A way to see if we single or dbl clicked

        #endregion Variables
        /* Ok now we have our constructors to write
         * All a Constructor is, is a way to access this class, lets say
         * we are inside the main game loop, and we wanted to change our mouse
         * we can then create a new instance of this mouse class by typing
         * MouseControl MyMouse = new MouseControl();
         * so now through the rest of the function we created this in
         * We can call all the functions in this class by doing a
         * MyMouse.currentmouse = (whatever) what this does is set the
         * current variable we are accessing, to whatever we want, by setting it
         * in the function we are writing.
         * All of the functions and or variables that we declare as public
         * can be accessed in this way.
         * private is only used within this class.
         */
        #region Constructors
        /* This is a normal constructor, which we wont be using here, because i always
         * want to pass the current screen width and height to the mouse when we call a function
         * I hope that way it will be eaiser to allow the user his own resolution.
        public MouseControl()
        {
        } */
        // We will use this constructor
        // Type 3 / like this before each function you make like /// and the below summary box opens
        /// <summary>
        /// Control to manipulate mouse functions
        /// </summary>
        /// <param name="windowwidth">The width of the current game window</param>
        /// <param name="windowheight">The height of the current game window</param>
        public MouseControl(int windowwidth, int windowheight, float doubleClickTime) // Always pass width and height to it
        {
            // Make both our mousestates as new blank ones
            currentmouse = new MouseState();
            oldmouse = new MouseState();

            Position = new Vector2(windowwidth / 2, windowheight / 2); // Always try to set this
            // As the center of the screen whatever that may be

            /* Creating a new rectangle, by using the X and Y position of our Vector2
             * This is invisible unless we make it not.
             */
            clickRectangle = new Rectangle((int)Position.X, (int)Position.Y, 3, 3);
                                                            /* Rectangles need int values, so we have to
                                                             * Convert the value of Vector2.X from a Vector2
                                                             * to a int which is why we use a cast (int)
                                                             * before it, if we wanted it to be a double (double)
                                                             * would do it.
                                                             * We need error checking to make sure our program
                                                             * doesnt just crash, but crashes with a reason why
                                                             * I will add that later as thats a freekun whole
                                                             * other topic lol
                                                             * But it pretty much just involves a try and a catch
                                                             * try
                                                             * {
                                                             * }
                                                             * catch (Exception r)
                                                             * {
                                                             * // Yell about error (r)
                                                             * }
                                                             */

                


            leftIsHeld = false; // Default is no its not held down

            screenwidth = windowwidth; // Setting our private varible screenwidth to whatever width we passed to this class

            screenheight = windowheight; // Same as above
        }

        #endregion Constructors
        #region Update Mouse

        /// <summary>

        /// This should be called every update cycle

        /// </summary>     

        public void UpdateMouse(GameTime gameTime)
        {

            #region Set Position

            oldmouse = currentmouse;

            currentmouse = Mouse.GetState();

            Position.X = currentmouse.X;

            Position.Y = currentmouse.Y;



            if (clickedonce && time < gametime.TotalGameTime.TotalSeconds)
            {

                clickedonce = false;

            }

            //This is to keep our mouse on the screen

            if (Position.X < 0)
            {

                Position.X = 0;

            }

            else if (Position.X > screenwidth)
            {

                Position.X = screenwidth;

            }

            if (Position.Y < 0)
            {

                Position.Y = 0;

            }

            else if (Position.Y > screenheight)
            {

                Position.Y = screenheight;

            }

            gametime = gameTime;

            clickRectangle.X = (int)Position.X;

            clickRectangle.Y = (int)Position.Y;

            #endregion SetPosition
            if (leftIsHeld == true)
            {

                if (currentmouse.LeftButton == ButtonState.Released)
                {

                    leftIsHeld = false;

                }

            }

            scrollWheelValue += currentmouse.ScrollWheelValue -

                oldmouse.ScrollWheelValue;

        }

        #endregion Update Mouse

        // Left Click
        #region Left Click

        /// <summary>

        /// Use this to determine if the left button was clicked

        /// </summary>

        /// <returns>if the left button was clicked</returns>

        public bool LeftClicked()
        {

            if (currentmouse.LeftButton == ButtonState.Pressed

                && oldmouse.LeftButton == ButtonState.Released)
            {

                clickedonce = true;

                time = gametime.TotalGameTime.TotalSeconds + .5f;

                return true;

            }

            else
            {

                return false;

            }

        }

        #endregion Left Click

        // Left Held
        #region Left Held

        /// <summary>

        /// Use this to determine if the left button is being held

        /// The tricky part is figuring out the difference

        /// between a drag and a long click.

        ///

        /// What we're doing is testing if we already determined

        /// if it's already being held, or if it's being held and

        /// it's been moved.

        /// Else we assume it's a long click.

        /// </summary>

        /// <returns>If the button is being held</returns>

        public bool LeftHeld()
        {

            if (currentmouse.LeftButton == ButtonState.Pressed

                && oldmouse.LeftButton == ButtonState.Pressed

                && leftIsHeld == true)
            {

                return true;

            }

            else if ((currentmouse.LeftButton == ButtonState.Pressed

                && oldmouse.LeftButton == ButtonState.Pressed) &&

                (currentmouse.X != oldmouse.X || currentmouse.Y != oldmouse.Y))
            {

                leftIsHeld = true;

                return true;

            }

            else
            {

                return false;

            }

        }

        #endregion Left Held

        // Right Clicked
        #region Right Clicked

        /// <summary>

        /// Use this to determine if the right button is

        /// being held

        /// </summary>

        /// <returns>If the right button was clicked</returns>

        public bool RightClick()
        {

            if (currentmouse.RightButton == ButtonState.Pressed

                && oldmouse.RightButton == ButtonState.Released)
            {

                return true;

            }

            else
            {

                return false;

            }

        }

        #endregion Right Clicked

        // Double Left Click
        #region Double Clicked
        /// <summary>

        /// Use this to determine if the left button was

        /// double clicked

        /// </summary>

        /// <returns>If the left button was double clicked</returns>

        public bool DoubleClick()
        {

            if (clickedonce)
            {

                if (currentmouse.LeftButton == ButtonState.Pressed

                && oldmouse.LeftButton == ButtonState.Released)
                {

                    clickedonce = false;

                    return true;

                }

                else
                {

                    return false;

                }

            }

            else
            {

                return false;

            }

        }
        #endregion Double Clicked

    } // End Class
} // End NameSpace
